/*
 * Visual Program Editor
 *
 * packages.cpp
 */


#include <QForms.hpp>
#include <QGraphics.hpp>
#include <QStdCtrls.hpp>
#include <SysUtils.hpp>
#include <stdio.h>
#pragma hdrstop

#include "uMainWindow.h"
#include "uProjectOptions.h"
#include "packages.h"
#include "Support.h"

TPackageList * PackageList;


namespace Classes
{
    void __fastcall (* RegisterComponentsProc) (const AnsiString Page, const TMetaClass * const * ComponentClasses, const int ComponentClasses_Size);
    void __fastcall (* RegisterNoIconProc) (const TMetaClass * const * ComponentClasses, const int ComponentClasses_Size);
};


void __fastcall TRegisterComponentsProc (const AnsiString Page, const TMetaClass * const * ComponentClasses, const int ComponentClasses_Size)
{
    int i, j;
    AnsiString Name;
    TSpeedButton * Button;
    TTabSheet * TabSheet;
    bool FindPlt = false;
    
    printf ("debug: RegisterComponentsProc\n");
    
    for (i = 0; i < MainWindow->Palette->ControlCount; i ++)
    {
	TabSheet = (TTabSheet *) MainWindow->Palette->Controls [i];
	if (TabSheet->Caption == Page)
	{
	    FindPlt = true;
	    break;
	}
    }
    
    if (!FindPlt)
    {
	TabSheet = new TTabSheet (MainWindow);
	TabSheet->PageControl = MainWindow->Palette;
	TabSheet->Caption = Page;
    }
    
    for (i = 0; i <= ComponentClasses_Size; i++)
    {
	bool HasReg = false;
	
	Name = ComponentClasses [i]->ClassName ();
	for (j = 0; j < TabSheet->ControlCount; j ++)
	{
	    if (TabSheet->Controls [i]->Hint == Name)
	    {
		HasReg = true;
		break;
	    }
	}

	if (HasReg) continue;

	Button = new TSpeedButton (TabSheet);
	Button->Hint = Name;
	Button->Align = alLeft;
	Button->Height = 40;
	Button->Width = 40;
	Button->Flat = true;
	Button->Parent = TabSheet;
	Button->ShowHint = true;
	Button->GroupIndex = 0xff;

	if (!Button->Glyph) Button->Glyph = new Qgraphics::TBitmap ();

	try
	{
	    Button->Glyph->LoadFromResourceName ((int) MainInstance, Name);
	}
	catch (...)
	{
	}
    }
}

void __fastcall TRegisterNoIconProc (const TMetaClass * const * ComponentClasses, const int ComponentClasses_Size)
{
}


void __fastcall InfoProc (const AnsiString Name, TNameType NameType, Byte Flags, void * Param)
{
    unsigned Module;

    TPackage * package = reinterpret_cast <TPackage *> (Param);
    
    printf ("InfoProc : %s ", Name.c_str ());

    switch (NameType)
    {
    case ntContainsUnit:
    {
        printf ("[ntContainsUnit]\n");

        AnsiString Proc = "@" + Name + "@Register$qqrv";
        TPackage::TRegisterProc RegisterProc = (TPackage::TRegisterProc) GetProcAddress (package->Handle, Proc.c_str ());

        if (RegisterProc)
        {
            printf ("+ Register %s\n", Name.c_str ());
            try { RegisterProc (); } catch (...) {}
            return;
        }
        break;
    }
    case ntRequiresPackage:
    {
        printf ("[ntRequiresPackage]\n");

        Module = LoadPackage (Name.c_str ());
        InitializePackage (Module);

        break;
    }
    case ntDcpBpiName:
    {
        printf ("[ntDcpBpiName]\n");
        break;
    }
    };
}


__fastcall TPackage::TPackage ()
{
    Items = new TComponentList;
}

__fastcall TPackage::~TPackage ()
{
    delete Items;
}

bool TPackage::Load (AnsiString FileName)
{
    int Pos;

    try
    {
	    Handle = LoadPackage (FileName);
	    GetPackageInfo (Handle, this, Flags, InfoProc);
    }
    catch (...)
    {
	return false;
    }
    
    ModuleName = GetModuleName (Handle);
    Description = GetPackageDescription (ModuleName.c_str ());
    
    return true;
}

bool TPackage::Unload (bool Force)
{
}

void TPackageList::Init ()
{
    Classes::RegisterComponentsProc = TRegisterComponentsProc;
    Classes::RegisterNoIconProc = TRegisterNoIconProc;

    PackageList = new TPackageList;
}

void TPackageList::Free ()
{
    int i;
    TPackage * package;
    
    for (i = 0; i < PackageList->Count; i ++)
    {
	package = reinterpret_cast <TPackage *> (PackageList->Items [i]);
	package->Unload (true);
    }

    delete PackageList;
}

